package com.sansan.qiangji.realize.base;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sansan.qiangji.VO.base.shelve.ShelveListResultVO;
import com.sansan.qiangji.VO.base.shelve.ShelveVO;
import com.sansan.qiangji.VO.base.shelve.ShelveWidthVO;
import com.sansan.qiangji.VO.base.stock.StockListResultVO;
import com.sansan.qiangji.VO.base.stock.StockVO;
import com.sansan.qiangji.entity.base.Product;
import com.sansan.qiangji.entity.base.Shelve;
import com.sansan.qiangji.entity.base.example.ProductExample;
import com.sansan.qiangji.entity.base.example.ShelveExample;
import com.sansan.qiangji.entity.base.Stock;
import com.sansan.qiangji.entity.base.example.StockExample;
import com.sansan.qiangji.enums.ResultEnum;
import com.sansan.qiangji.exception.ServiceException;
import com.sansan.qiangji.form.base.*;
import com.sansan.qiangji.service.impl.base.ProductServiceImpl;
import com.sansan.qiangji.service.inter.base.ShelveService;
import com.sansan.qiangji.service.inter.base.StockService;
import com.sansan.qiangji.utils.pageUtils.PageResult;
import com.sansan.qiangji.utils.pageUtils.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ShelveReal {
    @Autowired
    private ShelveService shelveService;
    @Autowired
    private StockService stockService;
    @Autowired
    private ProductServiceImpl productService;


    @Transactional
    public void deleteShelve(Integer shelveId) {
        Shelve shelve = shelveService.selectByPrimaryKey(shelveId);
        if (shelve == null) {
            log.error("【货架删除】货架不存在，shelveId={}", shelveId);
            throw new ServiceException(ResultEnum.SHELVE_IS_NOT_EXIST);
        }
        int row = shelveService.deleteByPrimaryKey(shelveId);
        if (row == 0) {
            log.error("【货架删除】货架删除失败，shelveId={}", shelveId);
            throw new ServiceException(ResultEnum.SHELVE_DELETE_ERROR);
        }
    }

    @Transactional
    public void addShelve(ShelveAddForm shelveAddForm) {
        ShelveExample example = new ShelveExample();
        example.or().andShelveNameEqualTo(shelveAddForm.getShelveName());
        List<Shelve> shelveList = shelveService.selectByExample(example);
        if (shelveList.size() > 0) {
            log.error("【货架新增】该货架名称或编号已存在，shelveName={}", shelveAddForm.getShelveName());
            throw new ServiceException(ResultEnum.SHELVE_IS_EXIST);
        }
        Shelve shelve = new Shelve();
        BeanUtils.copyProperties(shelveAddForm, shelve);
        int row = shelveService.insert(shelve);
        //新增货架同时生成库位表
        for (int i = 1; i <= shelveAddForm.getShelveHeight(); i++) {
            for (int j = 1; j <= shelveAddForm.getShelveWidth(); j++) {
                Stock stock = new Stock();
                stock.setStockHeight(i);
                stock.setStockWidth(j);
                stock.setShelveName(shelve.getShelveName());
                stock.setStockStatus("空闲");

                stockService.insert(stock);
            }
        }
        if (row == 0) {
            log.error("【货架新增】货架新增失败");
            throw new ServiceException(ResultEnum.SHELVE_INSERT_ERROR);
        }
    }


    @Transactional
    public void editShelve(ShelveEditForm shelveEditForm) {
        //todo 编辑货架如何更改库位
        Shelve shelve = new Shelve();
        BeanUtils.copyProperties(shelveEditForm, shelve);
        int row = shelveService.updateByPrimaryKey(shelve);
        if (row == 0) {
            log.error("【货架新增】货架新增失败");
            throw new ServiceException(ResultEnum.SHELVE_INSERT_ERROR);
        }
    }

    public ShelveListResultVO shelveList(ShelveListForm shelveListForm) {
        ShelveExample example = new ShelveExample();
        int pageNum = shelveListForm.getPageNum();
        int pageSize = shelveListForm.getPageSize();
        PageHelper.startPage(pageNum, pageSize);
        ShelveExample.Criteria criteria = example.createCriteria();
        if (shelveListForm.getShelveName() != null && !"".equals(shelveListForm.getShelveName())) {
            criteria.andShelveNameLike("%" + shelveListForm.getShelveName() + "%");
        }
        if (shelveListForm.getStackerName() != null && !"".equals(shelveListForm.getStackerName())) {
            criteria.andStackerNameLike("%" + shelveListForm.getStackerName() + "%");
        }
        if (shelveListForm.getWarehouseName() != null && !"".equals(shelveListForm.getWarehouseName())) {
            criteria.andWarehouseNameLike("%" + shelveListForm.getWarehouseName() + "%");
        }
        List<Shelve> shelveList = shelveService.selectByExample(example);
        PageResult<Shelve> shelvePageResult = PageUtil.getPageResult(new PageInfo<>(shelveList));
        ShelveListResultVO shelveListResultVO = new ShelveListResultVO();
        BeanUtils.copyProperties(shelvePageResult, shelveListResultVO);
        List<ShelveVO> shelveVOS = new ArrayList<>();
        StockExample stockExample = new StockExample();
        List<Stock> stockList = stockService.selectByExample(stockExample);
        for (Shelve shelve : shelvePageResult.getContent()) {
            ShelveVO shelveVO = new ShelveVO();
            BeanUtils.copyProperties(shelve, shelveVO);
            //查找货位分层
            List<ShelveWidthVO> widthVOS = new ArrayList<>();
            for (int i = shelveVO.getShelveWidth(); i >= 1; i--) {
                ShelveWidthVO shelveWidthVO = new ShelveWidthVO();
                shelveWidthVO.setWidth(i);
                final int width = i;
                List<Stock> stocks = stockList.stream().filter(e -> e.getShelveName().equals(shelveVO.getShelveName()) && e.getStockWidth() == width).collect(Collectors.toList());
                stocks.sort(Comparator.comparingInt(Stock::getStockHeight));
                /*StockExample stockExample = new StockExample();
                stockExample.or().andShelveNameEqualTo(shelveVO.getShelveName()).andStockWidthEqualTo(i);
                stockExample.setOrderByClause("stock_height asc");
                List<Stock> stockList = stockService.selectByExample(stockExample);*/
                List<StockVO> stockVOS = new ArrayList<>();
                for (Stock stock : stocks) {
                    StockVO stockVO = new StockVO();
                    BeanUtils.copyProperties(stock, stockVO);
                    stockVOS.add(stockVO);
                }
                shelveWidthVO.setStockVOS(stockVOS);
                widthVOS.add(shelveWidthVO);
            }
            shelveVO.setShelveWidthVOS(widthVOS);
            shelveVOS.add(shelveVO);
        }
        shelveListResultVO.setShelveVOS(shelveVOS);
        return shelveListResultVO;
    }

    //推荐货位
    public StockVO recommendEmptyPosition(String shelveName) {
        StockExample stockExample = new StockExample();
        stockExample.or().andShelveNameEqualTo(shelveName).andStockStatusEqualTo("空闲").andFreezeStatusEqualTo("正常");
        stockExample.setOrderByClause("stock_width desc,stock_height asc");
        List<Stock> stockList = stockService.selectByExample(stockExample);
        if (stockList == null || stockList.size() == 0) {
            log.error("【推荐货位】没有空闲货位");
            throw new ServiceException(ResultEnum.STOCK_IS_NOT_EMPTY_EXIST);
        } else {
            Stock stock = stockList.get(0);
            StockVO stockVO = new StockVO();
            BeanUtils.copyProperties(stock, stockVO);
            log.error("【推荐货位】,{}", stockVO);
            return stockVO;
        }
    }

    //
    public void changeFreezeStatus(StockChangeFreezeStatusForm freezeForm) {
        Stock stock = stockService.selectByPrimaryKey(freezeForm.getStockId());
        if (stock == null) {
            log.error("【冻结货位】查找不到该货位");
            throw new ServiceException(ResultEnum.STOCK_IS_NOT_EXIST);
        }
        stock.setFreezeStatus(freezeForm.getFreezeStatus());
        stockService.updateByPrimaryKey(stock);
    }

    public StockListResultVO groupCountByExample(StockListForm stockListForm) {
        StockExample example = new StockExample();
        int pageNum = stockListForm.getPageNum();
        int pageSize = stockListForm.getPageSize();
        PageHelper.startPage(pageNum, pageSize);
        if (stockListForm.getProductName() != null && !stockListForm.getProductName().equals("")) {
            example.or().andProductNameLike("%" +
                    stockListForm.getProductName() +
                    "%");
        }

        List<StockVO> stockVOS = stockService.groupCountByExample(example);
        PageResult<StockVO> stockPageResult = PageUtil.getPageResult(new PageInfo<>(stockVOS));
        StockListResultVO stockListResultVO = new StockListResultVO();
        BeanUtils.copyProperties(stockPageResult, stockListResultVO);
        //List<StockVO> stockVOList = stockPageResult.getContent();
        stockListResultVO.setStockVOS(stockPageResult.getContent());

        return stockListResultVO;

    }

    public StockListResultVO groupCountByCondition(StockListForm stockListForm) {
        List<Product> products = new ArrayList<>();
        if (stockListForm.getProductCode() != null && !stockListForm.getProductCode().equals("")) {
            ProductExample productExample = new ProductExample();
            productExample.or().andProductCodeEqualTo(stockListForm.getProductCode());
            products = productService.selectByExample(productExample);
        }
        int pageNum = stockListForm.getPageNum();
        int pageSize = stockListForm.getPageSize();
        PageHelper.startPage(pageNum, pageSize);
        if (stockListForm.getProductName() != null && !"".equals(stockListForm.getProductName())) {
        } else {
            stockListForm.setProductName(null);
        }
        if (stockListForm.getProductCode() != null && !"".equals(stockListForm.getProductCode())) {
        } else {
            stockListForm.setProductCode(null);
        }
        List<StockVO> stockVOS = stockService.groupCountByCondition(stockListForm);
        PageResult<StockVO> stockPageResult = PageUtil.getPageResult(new PageInfo<>(stockVOS));
        StockListResultVO stockListResultVO = new StockListResultVO();
        BeanUtils.copyProperties(stockPageResult, stockListResultVO);
        stockListResultVO.setStockVOS(stockPageResult.getContent());
        if (stockListResultVO.getStockVOS().size() == 0 && products.size() > 0) {
            StockVO stockVO = new StockVO();
            stockVO.setProductName(products.get(0).getProductName());
            stockVO.setProductCode(products.get(0).getProductCode());
            stockVO.setStockCount(0);
            stockVO.setUpperLimit(products.get(0).getUpperLimit());
            stockVO.setLowerLimit(products.get(0).getLowerLimit());
            stockVOS.add(stockVO);
            stockListResultVO.setStockVOS(stockVOS);
        }
        return stockListResultVO;
    }
}
